package com.zglc.ms.shop.service;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.zglc.ms.base.constants.ResponseCodeHelper;
import com.zglc.ms.base.service.BizServiceException;
import com.zglc.ms.shop.dao.PointDao;
import com.zglc.ms.shop.dao.ProductDao;
import com.zglc.ms.shop.dao.TransDao;
import com.zglc.ms.shop.dao.TransDao.TransModel;
import com.zglc.ms.shop.model.ShopProduct;

@Service
@Transactional
public class TransService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private TransDao transDao;

    @Autowired
    private PointDao pointDao;

    @Autowired
    private ProductDao productDao;

    public Integer save(int userId, long orderNo, int shopProductId, String priceDetail, int cnt, String payDetail,
            String payChannel, int platfrom, boolean isNeedSend, String remark, int sendAddressId, String address,
            String phone, String contact) {
        return transDao.save(userId, orderNo, shopProductId, priceDetail, cnt, payDetail, payChannel, platfrom,
                isNeedSend, remark, sendAddressId, address, phone, contact);
    }

    public int sumSuccess(int userId, int shopProductId) {
        return transDao.sumSuccess(userId, shopProductId);
    }

    public int sumSuccessMonth(int userId, int shopProductId, String yearMonthStr) {
        return transDao.sumSuccess(userId, shopProductId, yearMonthStr);
    }

    public TransModel get(String orderNo) {
        return transDao.get(orderNo);
    }

    public TransModel get(int transId) {
        TransModel transModel = transDao.get(transId);
        if (transModel != null) {
            long now = System.currentTimeMillis();
            if (transModel.getState() == TRANS_TYPE_APPLY
                    && transModel.getCreatedAt().getTime() + TIME_15_MINUTE < now) {
                transModel.setState(TRANS_TYPE_CANCEL);
                transDao.updateCancel(transModel.getId());
            }
        }

        return transModel;
    }

    public boolean updateCancel(int transId) {
        return transDao.updateCancel(transId);
    }

    public List<TransModel> getByUserId(int userId, int page, int pageNum) {
        List<TransModel> list = transDao.getByUserId(userId, page, pageNum);
        boolean isUpdate = false;
        if (!CollectionUtils.isEmpty(list)) {
            long now = System.currentTimeMillis();
            for (TransModel transModel : list) {
                if ((transModel.getState() == TRANS_TYPE_APPLY)
                        && (transModel.getCreatedAt().getTime() + TIME_15_MINUTE < now)) {
                    transDao.updateCancel(transModel.getId());
                    isUpdate = true;
                }
            }
        }

        if (isUpdate) {
            return transDao.getByUserId(userId, page, pageNum);
        }

        return list;
    }

    public Integer getByUserIdCnt(int userId) {
        return transDao.getByUserIdCnt(userId);
    }

    public boolean isOrderCancel(TransModel transModel) {
        long now = System.currentTimeMillis();
        if (transModel.getState() == TRANS_TYPE_CANCEL) {
            return true;
        }

        if (transModel.getState() == TRANS_TYPE_APPLY && transModel.getCreatedAt().getTime() + TIME_15_MINUTE < now) {
            transModel.setState(TRANS_TYPE_CANCEL);
            transDao.updateCancel(transModel.getId());
            return true;
        }

        return false;
    }

    // 订单锁定时间15分钟
    private final int TIME_15_MINUTE = CacheManagerUtil.PAY_VALID_TIME * 1000;

    private final int TRANS_TYPE_CANCEL = 5;

    private final int TRANS_TYPE_APPLY = 1;

    private final int SUBTYPE_BUY = 21;

    public void successProcess(int userId, ShopProduct shopProduct, int cnt, int id, boolean isAmountPay,
            String payOrderNo, int priceType, int totalPoint) throws BizServiceException {
        if (totalPoint > 0) {
            // 扣减积分
            if (!pointDao.updateUserPoint(userId, totalPoint, priceType)) {
                if (isAmountPay) {
                    // TODO 退钱
                    logger.info("退钱 userId = " + userId + " shopProduct = " + shopProduct.toString() + " cnt = " + cnt
                            + " id = " + id + " isAmountPay = " + isAmountPay + " totalPoint " + totalPoint
                            + " payOrderNo " + payOrderNo);
                }

                throw new BizServiceException(String.valueOf(ResponseCodeHelper.NOT_BUY_USER_POINTS_LOWER), "铜钱不够");
            }

            pointDao.insertDetailExpense(userId, id, SUBTYPE_BUY, priceType, totalPoint, new Date(),
                    shopProduct.getName());
        }

        // 扣减库存
        logger.info("开始更新库存: " + cnt);
        boolean isUpdateStock = productDao.updateShopStock(shopProduct.getId(), cnt);
        logger.info(" so " + isUpdateStock);
        // 不存在库存同时非现金支付[现金支付没库存了也得成交]
        if (!isUpdateStock) {
            if (!isAmountPay) {
                logger.info("库存更新失败 userId " + userId + " shopProduct " + shopProduct + " | " + isAmountPay);
                throw new BizServiceException(String.valueOf(ResponseCodeHelper.GOODS_HAS_NOT_STOCK), "库存不够");
            }

            productDao.updateShopStockNotLimitCount(shopProduct.getId(), cnt);
        }

        // 设置交易为成功
        boolean isUpdateSuccess = transDao.updateSuccessState(id, payOrderNo);
        if (!isUpdateSuccess) {
            throw new BizServiceException(String.valueOf(ResponseCodeHelper.COMMON_SYSTEM_EXCEPTION), "购买失败");
        }

    }

}